#!/usr/bin/env python2.5
#coding: utf8

#Author: Gang Li
#Date: 2010-04-10 18:20

import socket
import sys
import select
import time

from core.utils import *
from core.transport import Client, CmdFilter, HeartBeat, CmdDispatcher
from core.fs import FSRoot
from loader import MRImporter

import logging
logging.basicConfig(format="%(asctime)s %(levelname)s %(message)s", level=logging.INFO)
log = logging.getLogger("worker")

class Worker(CmdFilter):
    hb = HeartBeat()
    def __init__(self, srv_ip, srv_port, web_port):
        try:
            self.client = Client(srv_ip, srv_port, self)
            self.client.add_cmd_observer(self)
            self.client.add_cmd_observer(self.hb)
            MRImporter("http://%s:%s/" % (srv_ip, web_port)).install()
        except socket.error, e:
            log.warn("socket error%s", e)

    def disconnected(self, sock):
        self.client.close()
        self.fs.close()
        self.hb.close()
        log.info("disconnected")

    def connected(self, sock):
        self.fs = FSRoot.open(handler=self, mode="node")
        self.client.write(NODE_REG, "tasknode")
        def sender(id):
            self.client.write(id)
            log.info("try send hb msg, %s %s", id, sock)
        def on_failure(skt):
            log.info("hb failure %s", sock.getsockname())
        self.hb.add_observed(sock, sender, on_failure)

    def on_cmd(self, msg):
            id, data, skt = msg
            if id.startswith(FS_CMD):
                if self.fs: self.fs.on_cmd(id, data)
            elif id == TASK_NODE_ALLOC:
                #user data 
                gid = int(data)
                log.info("recv task alloc gid: %s" , gid)
                self.client.write(TASK_NODE_ALLOC_RSP, gid)
            elif id == START_SUB_TASK:
                self.do_task(data)
    def do_task(self, st):
        print "start worker:", st.name, st.type
        self.client.write(START_SUB_TASK_OK, st.id)
        try:
            #TODO reload module when module has already be loaded
            #but this is not 
            print dir()
            modu = __import__(st.name)
            print dir()
            if hasattr(modu, st.type): 
                getattr(modu, st.type)()
            else:
                st.error = 'no %s method' % st.type
    
            st.res['test'] = 'test'
        except BaseException, msg:
            st.error = msg
            print msg

        self.client.write(SUB_TASK_DONE, st)

    def reg_file(self, param):
        print param

    def reg_dir(self, param):
        print param
